class PromiseV3 {
    static PENDING = 'pending'
    static FULFILLED = 'fulfilled'
    static REJECTED = 'rejected'

    constructor(executor) {
        this.value = ''
        this.status = PromiseV3.PENDING
        this.callbacks = []
        if (typeof executor === "function") {
            try {
                executor(this.resolve.bind(this), this.reject.bind(this))
            } catch (e) {
                console.log(e)
            }
        } else {
            try {
                console.log(executor)
            } catch (e) {
                this.reject(e)
            }
        }

    }

    resolve(value) {
        this.value = value
        this.status = PromiseV3.FULFILLED
        this.callbacks.map(callback => {
            callback.onfulfilled(value)
        })
    }

    reject(reason) {
        console.log('reject')
    }

    then(onFulfilled, onRejected) {
        if (this.value === PromiseV3.PENDING) {
            try {
                this.callbacks.push({
                    onFulfilled: (data) => {
                        try {
                            this.resolve(data)
                        } catch (e) {
                            this.reject(e)
                        }
                    },
                    onRejected: (reason) => {
                        try {
                            this.reject(reason)
                        } catch (e) {
                            this.reject(e)
                        }
                    }
                })
            } catch (e) {
                this.reject(e)
            }
        }
        if (this.status === PromiseV3.FULFILLED) {
            setTimeout(() => {
                try {
                    onFulfilled(this.value)
                } catch (e) {
                    onRejected(e)
                }
            })
        }
        if (this.status === PromiseV3.REJECTED) {
            setTimeout(() => {
                try {
                    onRejected(this.value)
                } catch (e) {
                    onRejected(e)
                }
            })
        }
    }

    static resolve(value) {
        return new PromiseV3((resolve, reject) => {
            if (value instanceof PromiseV3) {
                value.then(resolve, reject)
            } else {
                resolve(value)
            }
        })
    }

    static reject(reason) {
        return new PromiseV3((resolve, reject) => {
            if (reason instanceof PromiseV3) {
                reason.then(resolve, reject)
            } else {
                reject(reason)
            }
        })
    }
    static all(promises) {
        const values = []
        return new PromiseV3((resolve, reject) => {
                promises.forEach(promise => {
                    promise.then(value => {
                        values.push(value)
                        if(promises.length === values.length){
                            resolve(values)
                        }
                    }, reason => {
                        reject(reason)
                    })
                })
        })
    }
    static race(promises) {
        return new PromiseV3((resolve, reject) => {
            promises.map(promise => {
                promise.then(value => {
                    resolve(value)
                }, reason => {
                    reject(reason)
                })
            })
        })
    }
}

// const p = new PromiseV3()



// 手写promise.all
function PromiseAll(promises) {
    return new Promise((resolve, reject) => {
        //第一个坑， 如果不是一个数组， 返回的应该是错误信息
        if(!Array.isArray(promises)) {
            return reject(new Error('传入的参数必须得是数组格式！'))
        }
        let  res = []
        let count = 0
        const promiseLength = promises.length
        promises.forEach((promise, index) => {
            // 第二个点， 这里应该是要判断promise是否是promise格式的， 因为可能是数字等其他格式。
            Promise.resolve(promise).then(result => {
                // 第三个点， 这里应该要有一个计数器， 因为promiseall是按照顺序返回的， 使用i就不是按照顺序了
                count ++
                res[index] = result
                // 第四个点， 这里如果使用length会有错， 因为， js中数组， 如果有第7个前面没有， 长度还是7(前面是undefined)
                if(count === promiseLength) resolve(res)
            }).catch(e => reject(e))
        })
    })
}










